﻿#region copyright
//                Copyright Andrew Rafas 2012.
// Distributed under the Eclipse Public License, Version 1.0.
//           (See accompanying file LICENSE.txt or 
//     copy at http://www.eclipse.org/legal/epl-v10.html)
#endregion
using System;
using System.Diagnostics.Contracts;
using System.Collections.Generic;

namespace CSFP
{
    public struct MapSeq<T, O, S> : ISeq<O, MapSeq<T, O, S>>, IEnumerable<O>
            where S : struct, ISeq<T, S>
    {
        readonly Func<T, O> _func;
        readonly S _current;

        public MapSeq(Func<T, O> func, S seq)
        {
            Contract.Requires<ArgumentNullException>(func != null);

            _func = func;
            _current = seq;
        }

        public bool IsValid { get { return _current.IsValid; } }
        public O First { get { return _func(_current.First); } }
        public MapSeq<T, O, S> Next { get { return new MapSeq<T, O, S>(_func, _current.Next); } }

        public IEnumerator<O> GetEnumerator() { return new SeqEnumerator<O, MapSeq<T, O, S>>(this); }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); }
    }

    public static partial class Functions
    {
        public static MapSeq<T, O, S> Map<T, O, S>(this S seq, Func<T, O> func)
            where S : struct, ISeq<T, S>
        {
            Contract.Requires<ArgumentNullException>(func != null);

            return new MapSeq<T, O, S>(func, seq);
        }
    }
}
